package com.infocollect.project.api.ui;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.infocollect.common.utils.AesUtil;
import com.infocollect.common.utils.DateUtils;
import com.infocollect.common.utils.oss.OSSClientUtil;
import com.infocollect.common.utils.oss.TYOSSClientUtil;
import com.infocollect.common.utils.poi.ExcelUtil;
import com.infocollect.framework.config.OSSConfig;
import com.infocollect.framework.web.domain.AjaxResult;
import com.infocollect.project.api.comm.WebApiHelper;
import com.infocollect.project.api.req.BatchDicEnumReq;
import com.infocollect.project.api.req.SignatureReq;
import com.infocollect.project.api.req.SwagggerInfoReq;
import com.infocollect.project.api.service.ApiCommService;
import com.infocollect.project.api.service.ICommService;
import com.infocollect.project.api.vo.*;
import com.infocollect.project.form.vo.HeadEntityVO;
import com.infocollect.project.form.vo.R;
import com.infocollect.project.api.vo.DictionaryEnumVO;
import com.infocollect.project.system.domain.SysUser;
import com.infocollect.project.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;


@Api(value = "comm", tags = "通用方法")
@Controller
@RequestMapping("comm")
public class CommController {
    @Autowired
    private ICommService commService;

    @Autowired
    private OSSClientUtil ossClient;
    @Autowired
    private TYOSSClientUtil tyOssClient;
    @Autowired
    private OSSConfig ossConfig;

    @Autowired
    private ApiCommService apiCommService;
    @Autowired
    private ISysUserService userService;
    private static final String separator = "/";

    @PostMapping("getDictionaryEnum")
    @ApiOperation("获取字典枚举")
    @ResponseBody
    public R<List<DictionaryEnumVO>> getDictionaryEnum(@RequestParam("menuType") String menuType) {
        return commService.getDictionaryEnum(menuType);
    }

    @PostMapping("getBatchDictionaryEnum")
    @ApiOperation("批量获取字典枚举")
    @ResponseBody
    public R<Map<String, List<DictionaryEnumVO>>> getBatchDictionaryEnum(@RequestBody BatchDicEnumReq batchMenuType) {
        return commService.getBatchDictionaryEnum(batchMenuType);
    }

    /**
     * 根据执行sql返回输出的字段名称
     *
     * @return
     */
    @ApiOperation("根据执行sql返回输出的字段名称")
    @PostMapping("getApiFieldNames")
    @ResponseBody
    public R<List<String>> getApiFieldNames(@RequestBody JSONObject param) throws Exception {
        return apiCommService.getApiFieldNames(param);
    }

    /**
     * 测试执行Api接口
     *
     * @param param
     * @return
     */
    @ApiOperation("测试执行Api接口")
    @PostMapping("testExecuteApi")
    @ResponseBody
    public R<Object> testExecuteApi(@RequestBody JSONObject param) throws Exception {
        return apiCommService.testExecuteApi(param);
    }

    /**
     * 导出xls
     *
     * @return 返回查询结果
     */
    @ApiOperation(value = "通用Exlce导出接口", notes = "")
    @PostMapping(value = "ExportExlce/{ApiCode}", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<String> ExportExlce(@RequestBody JSONObject param, @PathVariable("ApiCode") String ApiCode, HttpServletRequest req, HttpServletResponse response) throws Exception {
        return apiCommService.ExportExlce(param, ApiCode, response, req);
    }
    /**
     * 根据Api编码获取表头信息
     *
     * @return 返回查询结果
     */
    @ApiOperation(value = "根据Api编码获取表头信息", notes = "")
    @PostMapping(value = "getListHeadCell/{ApiCode}", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public R<List<HeadEntityVO>> getListHeadCell(@PathVariable("ApiCode") String ApiCode){
       return apiCommService.getListHeadCell(ApiCode);
    }
    /**
     * 通用接口
     *
     * @return 返回查询结果
     */
    @ApiOperation("通用接口")
    @PostMapping("apiComm/{ApiCode}")
    @ResponseBody
    public R<Object> apiComm(@RequestBody JSONObject param, @PathVariable("ApiCode") String ApiCode, HttpServletRequest req) throws Exception {
        return apiCommService.apiComm(param, ApiCode, req);
    }

    private static Set<String> imageTypeSet = new HashSet<>();
    private static Set<String> fileTypeSet = new HashSet<>();
    static {
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
        imageTypeSet.add(".jpeg");
        imageTypeSet.add(".tif");
        imageTypeSet.add(".bmp");
        //其他省略...
    }
    static {
        fileTypeSet.add(".txt");
        fileTypeSet.add(".doc");
        fileTypeSet.add(".xls");
        fileTypeSet.add(".docx");
        fileTypeSet.add(".xlsx");
        fileTypeSet.add(".pdf");
        fileTypeSet.add(".et");
        fileTypeSet.add(".jpg");
        fileTypeSet.add(".png");
        fileTypeSet.add(".gif");
        fileTypeSet.add(".jpeg");
        fileTypeSet.add(".tif");
        fileTypeSet.add(".bmp");
        //其他省略...
    }
    /**
     * Exlce 文件上传
     *
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "/uploadfile", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> uploadfile(@RequestParam(value = "imageFile", required = false) MultipartFile file, HttpServletRequest request,
                               HttpServletResponse response) {
        if (file == null || file.isEmpty()) {
            return R.newError("上传文件失败");
        }
        String fileName = file.getOriginalFilename();
        //String fileType = ".jpg";
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        if (!fileTypeSet.contains(fileType)) {
            return R.newError("请上传txt/doc/xls/docx/xlsx/jpg/gif/jpeg/png/pdf/et/tif/bmp格式的文件!");
        }
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String filePath = new File("AttachmentFile\\" + sdf.format(d)).getAbsolutePath();
        File fileUpload = new File(filePath);
        if (!fileUpload.exists()) {
            fileUpload.mkdirs();
        }
        UUID uuid = UUID.randomUUID();
        fileUpload = new File(filePath, uuid + fileType);
        if (fileUpload.exists()) {
            return R.newError("上传失败,上传的文件已存在");
        }
        try {
            file.transferTo(fileUpload);
            Map<String, String> dthashMap = new HashMap<>();
            dthashMap.put("name", fileName);
            dthashMap.put("uid", uuid.toString());
            dthashMap.put("size", file.getSize() + "");
            dthashMap.put("format", fileType);
            dthashMap.put("url", "/file/download?path="+ URLEncoder.encode("AttachmentFile\\" + sdf.format(d) + "\\" + uuid + fileType,"utf-8"));
            dthashMap.put("creater", "");
            Date createtime = new Date();
            SimpleDateFormat createtimesdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dthashMap.put("createtime", createtimesdf.format(createtime));
            return R.newOk(dthashMap);
        } catch (IOException e) {
            return R.newError("上传的文件失败：" + e.toString());
        }

    }
    /**
     * Exlce 文件上传
     *
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "/querySignature", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> querySignature(@RequestParam(value = "modelType", required = true) String modelType, @RequestBody SignatureReq signatureReq,  HttpServletRequest request,
                                    HttpServletResponse response) {
        try {
            String signatureJson = AesUtil.decode(signatureReq.getSignature());
            if(signatureJson==null)
            {
                return R.newError("签名错误");
            }
            Map<String, String> signMap = JSON.parseObject(signatureJson, HashMap.class);
            String time = signMap.get("time");
            Date curTime = DateUtils.parseDate(time);
            if(new Date().getTime() - curTime.getTime()>60000)
            {
                return R.newError("签名错误");
            }
        }catch(Exception ex)
        {
            return R.newError("签名错误");
        }

        if("init".equals(modelType))
        {
            try {
                if ("1".equals(ossConfig.getTyCloudFlag())) {
                    Map<String, String> respMap = tyOssClient.getSignature("");
                    return R.newOk(respMap);
                } else {
                    Map<String, String> respMap = new HashMap<String, String>();
                    respMap.put("tyCloudFlag", "0");

                    return R.newOk(respMap);
                }
            } catch (Exception ex) {
                return R.newError(ex.getMessage());
            }
        }
        else {
            String userId = "00000000";
            String dir = createFileDir(modelType, userId);

            try {
                if ("1".equals(ossConfig.getTyCloudFlag())) {
                    Map<String, String> respMap = tyOssClient.getSignature(dir);
                    return R.newOk(respMap);
                } else {
                    Map<String, String> respMap = ossClient.getSignature(dir);
                    return R.newOk(respMap);
                }
            } catch (Exception ex) {
                return R.newError(ex.getMessage());
            }
        }


    }
    /**
     * Exlce 文件上传
     *
     * @return
     * @throws Exception
     */
    @ApiOperation("文件上传")
    @RequestMapping(value = "/uploadImg", method = RequestMethod.POST)
    @ResponseBody
    public R<Object> uploadImg(@RequestParam(value = "imageFile", required = false) MultipartFile file, HttpServletRequest request,
                               HttpServletResponse response) {
        if (file == null || file.isEmpty()) {
            return R.newError("图片上传失败");
        }
        String fileName = file.getOriginalFilename();
        //String fileType = ".jpg";
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        if (!imageTypeSet.contains(fileType)) {
            return R.newError("请上传jpg/png/gif/jpeg/tif/bmp格式的文件!");
        }
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String filePath = new File("AttachmentFile\\" + sdf.format(d)).getAbsolutePath();
        File fileUpload = new File(filePath);
        if (!fileUpload.exists()) {
            fileUpload.mkdirs();
        }
        UUID uuid = UUID.randomUUID();
        fileUpload = new File(filePath, uuid + fileType);
        if (fileUpload.exists()) {
            return R.newError("图片上传失败,上传的图片已存在");
        }
        try {
            file.transferTo(fileUpload);
            Map<String, String> dthashMap = new HashMap<>();
            dthashMap.put("name", fileName);
            dthashMap.put("uid", uuid.toString());
            dthashMap.put("size", file.getSize() + "");
            dthashMap.put("format", fileType);
            dthashMap.put("url", "/file/downloadImg?path="+ URLEncoder.encode("AttachmentFile\\" + sdf.format(d) + "\\" + uuid + fileType,"utf-8"));
            dthashMap.put("creater", "");
            Date createtime = new Date();
            SimpleDateFormat createtimesdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            dthashMap.put("createtime", createtimesdf.format(createtime));
            return R.newOk(dthashMap);
        } catch (IOException e) {
            return R.newError("图片上传失败：" + e.toString());
        }

    }



    /**
     * Exlce 导入接口
     *
     * @param ApiCode
     * @param file
     * @param req
     * @param resp
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/importExlce/{ApiCode}", method = RequestMethod.POST)
    @ResponseBody
    public R<String> importExlce(@PathVariable("ApiCode") String ApiCode, MultipartFile file, HttpServletRequest req, HttpServletResponse resp) throws Exception {
        return R.newOk();
    }
    @ApiOperation("获取Swaggger文档信息")
    @RequestMapping(value = "/getSwagggerInfo", method = RequestMethod.POST)
    @ResponseBody
    public  R<String> getSwagggerInfo(@RequestBody SwagggerInfoReq param) throws  Exception{
      return R.newOk( WebApiHelper.AjaxGet(param.swagggerHttp + "/v2/api-docs"));
    }
    @ApiOperation("获取唯一的雪花ID")
    @RequestMapping(value = "/getNewId", method = RequestMethod.POST)
    @ResponseBody
    public R<Long> getNewId(){
      return R.newOk(IdWorker.getId());
    }

    private String createFileDir(final String modelType, final String userId) {
        String dir = ossConfig.getDirectory();
        StringBuilder sb = new StringBuilder();
        sb.append(separator);
        if ("image".equals(modelType)) // 图片文件
            sb.append("imageFile");
        else if ("other".equals(modelType)) // 文本文件
            sb.append("otherFile");
        else
            sb.append("otherFile");
        final Date date = new Date();
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("HHmmss");
        sb.append(separator).append(sdf1.format(date)).append(separator).append(userId).append(separator)
                .append(sdf2.format(date)).append(separator);
        return dir + sb.toString();
    }
}
